package xtreamclient


import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.apache.commons.lang3.RandomStringUtils
import vlccontrol.VLCControl
import java.beans.PropertyChangeEvent
import java.beans.PropertyChangeListener
import java.io.IOException
import java.util.logging.Logger

class TelnetVLCHandler() : VLCHandler{
    var isConnected = false
    val vlcControl = VLCControl()
    var currentTelnetPassword = ""
    override var process: Process? = null
    val listener = CrashListener()
    internal val log = inLog

    init {
        vlcControl.support.addPropertyChangeListener(listener)
    }

    override fun connect() {
        if (isConnected) {
            try {
                vlcControl.sendCommand("help")
            } catch (e:IOException) {
                startVLC()
                vlcControl.connect(currentTelnetPassword)
            }
        } else {
            startVLC()
            vlcControl.connect(currentTelnetPassword)
        }
        setupRegularCheck()
    }

    override fun playItem(streamURL: String, streamName: String) {
        try {
            vlcControl.sendCommand("stop")
            Thread.sleep(300)
            vlcControl.sendCommand("add $streamURL")
        } catch (e:IOException) {
            process?.destroyForcibly()
            startVLC()
            vlcControl.connect(currentTelnetPassword)
            vlcControl.sendCommand("add $streamURL")
        }
    }


    fun setupRegularCheck() {
        GlobalScope.launch {
            while (true) {
                delay(1500)
                if (checkStatus()) {
                    log.info("Still okay")
                } else {
                    log.severe("No connection after 20 tries")
                    process?.destroyForcibly()
                    startVLC()
                    vlcControl.connect(currentTelnetPassword)
                }
            }
        }
    }

    suspend fun checkStatus():Boolean {
        return listener.checkStatus(vlcControl)
    }

    class CrashListener : PropertyChangeListener {
        var hasAnswered = false
        suspend fun checkStatus(vlcControl: VLCControl):Boolean {
            hasAnswered = false
            try{
                vlcControl.sendCommand("status")
            } catch (e:IOException) {
                return false
            }
            repeat(20) {
                delay(500)
                if (hasAnswered) return true
            }
            return false
        }

        override fun propertyChange(evt: PropertyChangeEvent?) {
            hasAnswered = true
        }

    }


    private fun startVLC() {
        val length = 10
        val useLetters = true
        val useNumbers = false
        val generatedString = RandomStringUtils.random(length, useLetters, useNumbers)
        currentTelnetPassword = generatedString
        val rt = Runtime.getRuntime()
        process = rt.exec("\"C:\\Program Files\\VideoLAN\\VLC\\vlc.exe\"  --extraintf telnet --telnet-password $generatedString --telnet-port 4444")
    }

}